﻿using System;
using PoolKit.Commands;
using PoolKit.Extensions;

namespace PoolKit
{
    internal class PrepareForReuseCommand<TResource> : ResourceCommand<TResource>
        where TResource : class
    {
        private readonly ReusePreparationStrategy<TResource> _reusePreparationStrategy;
        private readonly IResourceCollection<TResource> _resourceCollection;

        public PrepareForReuseCommand(ReusePreparationStrategy<TResource> reusePreparationStrategy, IResourceCollection<TResource> resourceCollection, TResource resource):
            base(resource)
        {
            if (reusePreparationStrategy == null) throw new ArgumentNullException("reusePreparationStrategy");
            if (resourceCollection == null) throw new ArgumentNullException("resourceCollection");

            _reusePreparationStrategy = reusePreparationStrategy;
            _resourceCollection = resourceCollection;
        }

        /// <summary>
        /// </summary>
        /// <exception cref="FailedToPrepareResourceForReuseException"></exception>
        public override void Execute()
        {
            try
            {
                _reusePreparationStrategy.PrepareForReuse(Resource);
                _resourceCollection.AcceptBack(Resource);
            }
            catch (CannotAcceptResourceException)
            {
                throw;
            }
            catch (Exception exception)
            {
                if (exception.IsNotWrappable())
                {
                    throw;
                }

                throw new FailedToPrepareResourceForReuseException(
                    Resources.ReusePreparationStrategyFailed
                    .FormatWith(Environment.NewLine, _reusePreparationStrategy.ToString(), Resource.ToString()),
                    exception);
            }
        }
    }
}